package com.ruoyi.system.mapper;


import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

// 说明与备注:
// setMapUnderscoreToCamelCase不起作用, 手动配置也不起作用，解决方案如下：
// 方法1： 使用mapUnderscoreToCamelCase时一定要有又对应的实体类做映射
// 方法2：写select 语句的时候，字段名怎么写(例如小写、大写或Camel），映射的map的属性名与字段名完全一致（as的字段记得加引号）

@Mapper
@Repository
public interface DynamicMapper {
    @Select("${sqlStr}")
    List<LinkedHashMap<String,Object>> simpleQuery1(@Param(value = "sqlStr") String sqlStr);
    @Select("${sqlStr}")
    List<LinkedHashMap<String,Object>> simpleQuery2(@Param(value = "sqlStr") String sqlStr, @Param(value = "key") String Key);
    @Select("${sqlStr}")
    List<LinkedHashMap<String,Object>> query(@Param(value = "sqlStr") String sqlStr, @Param(value = "params") Map<String, Object> params);

    default List<LinkedHashMap<String,Object>> query(String table, String queryField, String whereKey, Object whereValue){
        return query(table, Arrays.asList(queryField), whereKey, whereValue);
    }
    default List<LinkedHashMap<String,Object>> query(String table, List<String> queryField, String whereKey, Object whereValue){
        return query(table, queryField, whereKey, whereValue, null);
    }
    default List<LinkedHashMap<String,Object>> query(String table, String queryField, String whereKey, Object whereValue, String whereAndOtherwise){
        return query(table, Arrays.asList(queryField), whereKey, whereValue, whereAndOtherwise);
    }
    default List<LinkedHashMap<String,Object>> query(String table, List<String> queryField, String whereKey, Object whereValue, String whereAndOtherwise) {
        String str = String.format("select %s from %s where %s = #{params.%s}",
                String.join(",", queryField), table, whereKey, whereKey);
        if (StringUtils.isNotEmpty(whereAndOtherwise)) str = str.concat(" and ").concat(whereAndOtherwise);
        try {
            Map<String, Object> params = new HashMap<>();
            params.put(whereKey, whereValue);
            return query(str, params);
        } catch (Exception e) {
            System.out.println(str);
            throw e;
        }
    }
    default List<LinkedHashMap<String,Object>> query(String table, List<String> queryField,
                                                     Map<String, Object> whereKeyValues,
                                                     String whereOtherwise){
        String where="";
        Map<String,Object> params = new HashMap<>();
        if(MapUtils.isNotEmpty(whereKeyValues)){
            AtomicReference<String> whereKeyValueAtom= new AtomicReference<String>("");
            whereKeyValues.forEach((k,v)->{
                String a=whereKeyValueAtom.get();
                if(StringUtils.isNotEmpty(a)) a += " and ";
                a += k + "= #{params."+k+"}";
                whereKeyValueAtom.set(a);
                params.put(k,v);
            });
            where=whereKeyValueAtom.get();
        }

        String str = String.format("select %s from %s where %s",
                String.join(",",queryField), table, where);
        if(StringUtils.isNotEmpty(whereOtherwise)) {
            str = str.concat(whereOtherwise);
        }
        try {
            return query(str,params);
        }catch (Exception e){
            System.out.println(str);
            throw e;
        }
    }

}
